<template>
  <div class="card">
    <div class="flex justify-between mb-3">
      <div class="flex items-center">
        <div class='col-span-1 mr-3'>
          <img v-if="data?.data.detail.type === 1" :src="bashIco" class="h-11 w-11"/>
          <img v-if="data?.data.detail.type === 2" :src="pythonIco" class="h-11 w-11"/>
        </div>
        <div class="">
          <div class="font-bold">{{ data?.data.detail.name }}</div>
          <div class="grid grid-cols-3 gap-x-6  mt-2">
            <div class="">
              <Tag v-if="data?.data.detail.type === 1" severity="info">SHELL</Tag>
              <Tag v-else-if="data?.data.detail.type === 2" severity="info">PYTHON3</Tag>
              <Tag v-else>未知</Tag>
            </div>
            <div class="col">
              <Tag v-if="data?.data.detail.tags?.length > 0" severity="info">{{
                  data?.data.detail.tags
                }}
              </Tag>
              <Tag v-else severity="info">未知</Tag>
            </div>
            <div class="col-9">
              {{ data?.data.detail.desc || '无' }}
            </div>
          </div>
        </div>
      </div>

      <div class="col flex flex-row-reverse items-start">
        <div class="mb-3 ml-2">
          <Button type="button" severity="secondary" icon="pi pi-ellipsis-v" @click="toggle"
                  aria-haspopup="true" aria-controls="overlay_menu"/>
          <Menu ref="moreMenu" id="overlay_menu" :model="moreItems" :popup="true">
            <template #item="{ item, props }">
              <a v-ripple class="flex items-center text-red-500" v-bind="props.action"
                 @click='requireConfirmation()'>
                <span :class="item.icon"/>
                <span class="ml-1">{{ item.label }}</span>
              </a>
            </template>
          </Menu>
        </div>
        <Button class="mb-3 ml-2" @click="updateToolkit" severity="secondary">保存</Button>
        <Button class="mb-3 ml-2" severity="secondary" @click="() => refEditor.visible(toolId)">编辑</Button>
        <Button class="mb-3 ml-2" severity="secondary"
                @click="() => router.push({path: '/toolkit/history-log/', query: {_id: toolId}})">日志
        </Button>
        <Button class="mb-3 ml-2" @click="showRun">执行</Button>
      </div>
    </div>
    <div class="grid grid-cols-12 gap-4">
      <div class="col-span-9">
        <div class="p-3 rounded-lg bg-gray-800">
          <v-ace-editor
              v-model:value="editorFormState.content"
              :lang="aceState.lang"
              theme="chaos"
              style="height: 65vh"/>
        </div>
      </div>
      <div class="col-span-3">
        <div class="px-3">
          <div class="border border-gray-300 rounded-lg">
            <span class="text-gray-900 font-bold block border-b border-gray-300 p-3">运行控制</span>
            <div class="p-3">
              <div class="bg-gray-100 p-3 flex items-center rounded-lg">
                <span class="text-gray-900 font-semibold mr-3">运行用户：</span>
                <div class="font-medium w-36">
                  <Inplace :closable="true">
                    <template #closeicon>
                      <Button class="h-4" icon="pi pi-check"></Button>
                    </template>
                    <template #display>
                      {{ editorFormState.exec_user || '默认' }}
                    </template>
                    <template #content>
                      <InputText class="w-36 mr-1" v-model="editorFormState.exec_user" autofocus/>
                    </template>
                  </Inplace>
                </div>
              </div>
            </div>
            <div class="p-3 pt-0">
              <div class="bg-gray-100 p-3 flex items-center rounded-lg">
                <span class="text-gray-900 font-semibold mr-3">工作目录：</span>
                <span class="font-medium w-36">
                                    <Inplace :closable="true">
                                        <template #closeicon>
                                            <Button class="h-4" icon="pi pi-check"></Button>
                                        </template>
                                        <template #display>
                                            {{ editorFormState.workspace || '默认' }}
                                        </template>
                                        <template #content>
                                            <InputText class="w-36 mr-1" v-model="editorFormState.workspace" autofocus/>
                                        </template>
                                    </Inplace>
                                </span>
              </div>
            </div>
          </div>

          <div class="border border-gray-300 rounded-lg mt-5">
            <span class="text-gray-900 font-bold block border-b border-gray-300 p-3">参数引用</span>
            <div class="p-3">
              <Tag v-for="(tags, index) in editorFormState.args" @click="() => showEditorModal(index)"
                   severity="info" class="mx-1 p-2">{{ tags.name }}
              </Tag>
              <Button icon="pi pi-plus" aria-label="Submit"
                      @click="()=> {visible.argsModal = true;restForm();pfd._editor = false}"/>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>

  <Dialog v-model:visible="visible.argsModal" modal :header="pfd._editor? '编辑参数' : '添加参数'"
          :style="{ width: '42rem' }">
    <Form v-slot="$form" :initialValues :resolver @submit="onSubmit" >
      <div class="mt-5 grid   grid-cols-2 gap-x-6">
        <div>
          <label class="text-sm font-semibold leading-6 text-gray-900">参数ID</label>
          <div class="mt-2">
            <InputText name="id" v-model="pfd.id" class="flex-auto w-full" autocomplete="off"/>
            <Message v-if="$form.id?.invalid" severity="error" size="small" variant="simple">
              {{ $form.id.error?.message }}
            </Message>
          </div>
        </div>
        <div>
          <label class="text-sm font-semibold leading-6 text-gray-900">参数名称</label>
          <div class="mt-2">
            <InputText name="name" v-model="pfd.name" class="flex-auto w-full" autocomplete="off"/>
            <Message v-if="$form.name?.invalid" severity="error" size="small" variant="simple">
              {{ $form.name.error?.message }}
            </Message>
          </div>
        </div>
      </div>


      <div class="mt-5 grid   grid-cols-2 gap-x-6">
        <div>
          <label class="text-sm font-semibold leading-6 text-gray-900">类型</label>
          <div class="mt-2">
            <Dropdown
                name="type"
                optionLabel="label"
                optionValue='value'
                v-model="pfd.type"
                @change="() => pfd.value = ''"
                :options="[
                    { value: 'one_str', label: '单行文本' },
                    { value: 'multi_str', label: '多行文本' },
                    { value: 'enums', label: '枚举' },
                    { value: 'bool', label: '布尔', disabled: pfd.type !== 2 },
                    { value: 'number', label: '数字' },
                    { value: 'password', label: '密码' },
                    { value: 'image', label: '图片' }
                ]"
                class="w-full"
            />
            <Message v-if="$form.type?.invalid" severity="error" size="small" variant="simple">
              {{ $form.type.error?.message }}
            </Message>
          </div>
        </div>

        <div class="flex">
          <div>
            <label class="text-sm font-semibold leading-6 text-gray-900">必填</label>
            <div class="mt-2 flex flex-wrap gap-3">
              <div class="flex items-center">
                <RadioButton v-model="pfd.require" inputId="ingredient1" name="require" :value="true"/>
                <label for="ingredient1" class="ml-2">是</label>
              </div>
              <div class="flex items-center">
                <RadioButton v-model="pfd.require" inputId="ingredient2" name="require" :value="false"/>
                <label for="ingredient2" class="ml-2">否</label>
              </div>
            </div>
          </div>
          <div class="ml-5">
            <label class="text-sm font-semibold leading-6 text-gray-900">私有</label>
            <div class="mt-2 flex flex-wrap gap-3">
              <div class="flex items-center">
                <RadioButton v-model="pfd.private" inputId="private" name="private" :value="true"/>
                <label for="private" class="ml-2">是</label>
              </div>
              <div class="flex items-center">
                <RadioButton v-model="pfd.private" inputId="private2" name="private" :value="false"/>
                <label for="private2" class="ml-2">否</label>
              </div>
            </div>
          </div>
        </div>

      </div>

      <div v-if="pfd.type === 'enums'" class="mt-5">
        <label class="text-sm font-semibold leading-6 text-gray-900">枚举值</label>
        <div class="flex flex-wrap mt-2">
          <div v-for="(item, index) in pfd.enums"
               class="flex items-center bg-gray-200 rounded-full px-2 py-1 mr-2">
            <div>{{ item }}</div>
            <i class="pi pi-times-circle text-sm cursor-pointer ml-2"
               @click="() => pfd.enums.splice(index, 1)"></i>
          </div>
          <InputText
              v-if="tmpEnumsActive"
              v-model="tmpEnumsCurrent"
              @blur="appendEnums"
              class="w-28 mr-2"
          />
          <Button v-if="!tmpEnumsActive" size="small" severity="secondary"
                  @click="() => tmpEnumsActive = true">新增
          </Button>
          <Button v-if="tmpEnumsActive" size="small" severity="secondary"
                  @click="() => { appendEnums(); tmpEnumsActive = false }">添加
          </Button>
        </div>
      </div>
      <div class="mt-5">
        <div>
          <label class="text-sm font-semibold leading-6 text-gray-900">默认值</label>
          <div class="mt-2">
            <InputText v-model="pfd.value" v-if="pfd.type === 'one_str'" class="w-full"/>
            <Textarea v-model="pfd.value" v-else-if="pfd.type === 'multi_str'" class="w-full"/>
            <InputNumber v-model="pfd.value" v-else-if="pfd.type === 'number'" class="w-full"/>
            <Password v-model="pfd.value" :feedback="false" v-else-if="pfd.type === 'password'" class="w-full"/>
            <div v-else-if="pfd.type === 'bool'" class="flex flex-col">
              <div class="flex flex-wrap gap-3">
                <div class="flex items-center">
                  <RadioButton v-model="pfd.value" name="boolValue1" :value="true"/>
                  <label for="boolValue1" class="ml-2">是</label>
                </div>
                <div class="flex items-center">
                  <RadioButton v-model="pfd.value" name="boolValue2" :value="false"/>
                  <label for="boolValue2" class="ml-2">否</label>
                </div>
              </div>
            </div>
            <SelectButton v-else-if="pfd.type === 'enums'" v-model="pfd.value" :options="pfd.enums" class="w-full"/>
          </div>
        </div>
      </div>

      <div class="mt-5">
        <label class="text-sm font-semibold leading-6 text-gray-900">说明</label>
        <div class="mt-2">
          <Textarea v-model="pfd.desc" rows="3" class="w-full"/>
        </div>
      </div>

      <div class="flex justify-between gap-2 mt-5">
        <Button type="button" label="删除" severity="danger" @click="removeArg"></Button>
        <div>
          <Button type="button" label="取消" severity="secondary"
                  @click="() => visible.argsModal = false"></Button>
          <Button type="submit" label="提交" class="ml-2"></Button>
        </div>

      </div>
    </Form>

  </Dialog>

  <ConfirmDialog></ConfirmDialog>

  <RunTool ref="refRun"></RunTool>
  <editor ref="refEditor" @refresh="refresh"></editor>
</template>


<script setup>
import {computed, reactive, ref, watch} from 'vue';
import {useRequest} from 'ahooks-vue';
import {ApiDelete, ApiDetail, ApiUpdate} from "@/api/toolkit.js";

import {VAceEditor} from 'vue3-ace-editor';
import 'ace-builds/src-noconflict/mode-python'; // Load the language definition file used below
import 'ace-builds/src-noconflict/mode-sh'; // Load the language definition file used below
import 'ace-builds/src-noconflict/theme-chaos'; // Load the theme definition file used below

import {useRoute, useRouter} from "vue-router";
import RunTool from "@/views/toolkit/RunTool.vue";
import pythonIco from '@/assets/python.png'
import bashIco from '@/assets/bash.ico'
import {useToast} from "primevue/usetoast";

import editor from "@/views/toolkit/editor.vue";
import {useConfirm} from "primevue/useconfirm";
import ConfirmDialog from 'primevue/confirmdialog';


import {Form} from '@primevue/forms';
import {yupResolver} from '@primevue/forms/resolvers/yup';
import * as yup from 'yup';

const route = useRoute();
const toolId = route.query.id
const refRun = ref()
const refEditor = ref()
const router = useRouter()

const toast = useToast();

const aceState = reactive({
  lang: 'python',
})

const visible = reactive({
  argsModal: false,
  editorModal: false,
  setArgsFile: false
})
const editorFormState = ref({
  target: {}
});
const argsEditorFormState = ref();
const argsSelectIndex = ref(-1);


watch(() => editorFormState.value.content, (newValue) => {
  if (refRun.value !== undefined)
    refRun.value.setContent(newValue)
})


const pfd = ref({});
const initialValues = reactive({});

function restForm() {

  initialValues.id = ""
  initialValues.name = ""
  initialValues.type = 'one_str'
  initialValues.require = true
  initialValues.private = true
  initialValues.value = ""
  initialValues.desc = ""
  initialValues.enums = []

  pfd.value = {...initialValues}

}

const resolver = yupResolver(
    yup.object({
      id: yup.string().min(2, '内容过少').max(20, '内容过多').required('必填项'),
      name: yup.string().min(2, '内容过少').max(20, '内容过多').required('必填项'),
      type: yup.string().min(2, '内容过少').max(10, '内容过多').required('必填项'),
      require: yup.bool().required('必填项'),
      // 验证 eEnums 为数组，数组中每个元素都是字符串
      enums: yup.array().test('enums', '枚举必填', () => {
        if (pfd.type !== 'enums') {
          return true
        }
        return pfd.enums.length > 1;
      })
    })
);


let tmpEnums = ref([])
let tmpEnumsCurrent = ref('')
let tmpEnumsActive = ref()
let aEditId = -1


const onSubmit = async ({valid}) => {
  if (!valid)
    return

  if (!Array.isArray(editorFormState.value.args)) {
    editorFormState.value.args = []
  }
  if (pfd.value._editor) {
    editorFormState.value.args[pfd.value._index] = {...pfd.value}
  } else {
    editorFormState.value.args.push({...pfd.value})

  }
  visible.argsModal = false
}

const appendEnums = (event) => {
  event.stopPropagation()
  pfd.value.enums.push(tmpEnumsCurrent.value)
  tmpEnumsCurrent.value = ''
}

// API
const {data, loading, refresh} = useRequest(ApiDetail, {defaultParams: [{id: toolId}], onSuccess: initForm})

function initForm(e) {
  editorFormState.value = e.data.detail
  if (editorFormState.value.args === null) {
    editorFormState.value.args = []
  }
  if (editorFormState.value.target === null || editorFormState.value.target === undefined) {
    editorFormState.value.target = {}
  }

  if (editorFormState.value.type === 1) {
    aceState.lang = 'sh'
  } else if (editorFormState.value.type === 2) {
    aceState.lang = 'python'
  }
}

const showRun = () => {
  refRun.value.setContent(editorFormState.value.content)
  refRun.value.show(toolId)
}
const updateToolkit = async () => {
  let params = {...editorFormState.value}
  params['id'] = toolId
  const result = await ApiUpdate(params);
  if (result.code === 0) {
    toast.add({severity: 'success', summary: '成功', detail: result.msg, life: 3000});
    refresh()
  } else {
    toast.add({severity: 'danger', summary: '错误', detail: result.msg, life: 3000});
  }

  await refresh()
};
const showEditorModal = (index) => {
  const eValues = {...editorFormState.value.args[index]}

  initialValues._editor = true
  initialValues._index = index
  initialValues.id = eValues.id
  initialValues.name = eValues.name
  initialValues.type = eValues.type
  initialValues.private = eValues.private
  initialValues.require = eValues.require
  initialValues.value = eValues.value
  initialValues.enums = eValues.enums

  pfd.value = {...initialValues}

  visible.argsModal = true;
};

const removeArg = () => {
  editorFormState.value.args.splice(aEditId, 1)
  aEditId = -1

  visible.argsModal = false;
}

const moreMenu = ref();
const moreItems = ref([
  {
    label: '删除',
    icon: 'pi pi-trash',
  },
]);

const toggle = (event) => {
  moreMenu.value.toggle(event);
};

const confirm = useConfirm();

const requireConfirmation = () => {
  confirm.require({
    message: '确定要删除该脚本吗？',
    header: '删除提示',
    icon: 'pi pi-info-circle',
    rejectLabel: '取消',
    rejectProps: {
      label: '取消',
      severity: 'secondary',
      outlined: true
    },
    acceptProps: {
      label: '删除',
      severity: 'danger'
    },
    accept: async () => {
      const result = await ApiDelete(toolId)
      if (result.code === 0) {
        router.back()
        toast.add({severity: 'success', summary: '删除成功', detail: result.msg, life: 3000});
      } else {
        toast.add({severity: 'danger', summary: '错误', detail: result.msg, life: 3000});
      }
    },
  });
};

</script>

<style scoped>
.tag-list {
  margin-right: 10px;

}
</style>
